package com.hejia.alauda.service;

import static org.springframework.util.ObjectUtils.isEmpty;
import static org.springframework.util.StringUtils.quoteIfString;

import java.io.StringWriter;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import com.alibaba.fastjson.JSONObject;
import com.hejia.alauda.entity.FinancialAsset;
import com.hejia.alauda.entity.FinancialAssetStockEntry;
import com.hejia.alauda.entity.Financing;
import com.hejia.alauda.entity.Presell;
import com.hejia.alauda.entity.Product;
import com.hejia.alauda.entity.Product.Category;
import com.hejia.alauda.entity.ProductEarningsRule;
import com.hejia.alauda.entity.ProductType;
import com.hejia.alauda.entity.ProductTypeField;
import com.hejia.alauda.entity.ProductTypeValue;
import com.hejia.alauda.entity.Protocol;
import com.hejia.alauda.entity.SaleActivity;
import com.hejia.alauda.entity.SaleNotify;
import com.hejia.alauda.entity.Template;
import com.hejia.alauda.entity.TemplateField;
import com.hejia.alauda.entity.TemplateValue;
import com.hejia.alauda.entity.User;
import com.hejia.alauda.entity.example.Example.Criteria;
import com.hejia.alauda.entity.example.FinancingExample;
import com.hejia.alauda.entity.example.OrderExample;
import com.hejia.alauda.entity.example.ProductExample;
import com.hejia.alauda.entity.example.ProductTypeExample;
import com.hejia.alauda.entity.example.ProductTypeFieldExample;
import com.hejia.alauda.entity.example.ProductTypeValueExample;
import com.hejia.alauda.entity.example.ProtocolExample;
import com.hejia.alauda.entity.example.SaleNotifyExample;
import com.hejia.alauda.entity.example.TemplateExample;
import com.hejia.alauda.entity.example.TemplateFieldExample;
import com.hejia.alauda.entity.example.TemplateValueExample;
import com.hejia.alauda.exception.BusinessException;
import com.hejia.alauda.jms.AlaudaEvent;
import com.hejia.alauda.jms.AlaudaSender;
import com.hejia.alauda.persistence.mybatis.FinancialAssetMapper;
import com.hejia.alauda.persistence.mybatis.FinancingMapper;
import com.hejia.alauda.persistence.mybatis.OrderMapper;
import com.hejia.alauda.persistence.mybatis.ProductEarningsRuleMapper;
import com.hejia.alauda.persistence.mybatis.ProductMapper;
import com.hejia.alauda.persistence.mybatis.ProductTypeFieldMapper;
import com.hejia.alauda.persistence.mybatis.ProductTypeMapper;
import com.hejia.alauda.persistence.mybatis.ProductTypeValueMapper;
import com.hejia.alauda.persistence.mybatis.ProtocolMapper;
import com.hejia.alauda.persistence.mybatis.SaleNotifyMapper;
import com.hejia.alauda.persistence.mybatis.TemplateFieldMapper;
import com.hejia.alauda.persistence.mybatis.TemplateMapper;
import com.hejia.alauda.persistence.mybatis.TemplateValueMapper;
import com.hejia.alauda.persistence.mybatis.UserMapper;
import com.hejia.alauda.utils.Pager;
import com.hejia.alauda.utils.Utils;
import com.hejia.hermes.entity.SMS;
import com.hejia.hermes.service.SMSService;

@Service
public class ProductServiceImpl implements ProductService {

	protected final Log logger = LogFactory.getLog(getClass());

	@SuppressWarnings("rawtypes")
	@Resource
	private RedisTemplate redisTemplate;

	@Resource
	private CommonService commonService;

	@Resource
	private ProductMapper productMapper;

	@Resource
	private OrderMapper orderMapper;

	@Resource
	private UserMapper userMapper;
	
	@Resource(name = "sendSMS")
	private SMSService smsService;

	@Resource
	private FinancingMapper financingMapper;

	@Resource
	private BalanceAndFinancingService balanceAndFinancingService;

	@Resource
	private FinancialAssetMapper financialAssetMapper;

	@Resource
	private ProductTypeMapper productTypeMapper;

	@Resource
	private ProductTypeFieldMapper fieldMapper;

	@Resource
	private ProductTypeValueMapper valueMapper;

	@Resource
	private TemplateMapper templateMapper;

	@Resource
	private TemplateValueMapper templateValueMapper;

	@Resource
	private TemplateFieldMapper templateFieldMapper;

	@Resource
	private ProtocolMapper protocolMapper;

	@Resource
	private ProductEarningsRuleMapper productEarningsRuleMapper;

	@Resource
	private CalendarService calendarService;

	@Resource
	private PresellService presellService;
	
	@Resource
	private SaleNotifyMapper saleNotifyMapper;
	
	@Resource
	private OrderService orderService;
	
	@Resource
	private FinancingService financingService;

	@Resource
	private SaleActivityService saleActivityService;
	
	
	private static long lastSendTime = 0;
	
	/**
	 * 预售列表
	 */
	@Override
	@Transactional(readOnly = true)
	public Pager<Product> getPresellProducts(Pager<Product> pager, String channel) {
		if (pager != null) {
			ProductExample example = new ProductExample();
			example.appendCriterion("startTime>", new Date());
			example.appendCriterion("tag!=4");
			if(StringUtils.isNotBlank(channel)){
				example.appendCriterion("(channel = '" + channel + "' or channel = '')");
			}
				
			else
				example.appendCriterion("channel = ''");
			example.appendCriterion("status=", "PUBLISHED");
			pager.setList(productMapper.selectByExample(example, pager));
		}
		return pager;
	}

	/**
	 * 在售列表
	 */
	@Override
	public Pager<Product> getOnsellProducts(Pager<Product> pager, String channel) {
		if (pager != null) {
			Date now = new Date();
			ProductExample example = new ProductExample();
			example.appendCriterion("(IFNULL(unpayAmount,0)>0 or totalAmount>IFNULL(soldAmount,0))");
			example.appendCriterion("startTime<=", now);
			example.appendCriterion("endTime>=", now);
			example.appendCriterion("tag!=4");
			if(StringUtils.isNotBlank(channel))
			{
				example.appendCriterion("(channel = '" + channel + "' or channel = '')");
			}
			else
				example.appendCriterion("channel = ''");
			example.appendCriterion("status=", "PUBLISHED");
			example.setOrderByClause("rookie, createDate desc");
			pager.setList(productMapper.selectByExample(example, pager));
		}
		return pager;
	}
	
	/**
	 * 售完列表
	 */
	public Pager<Product> getSoldoutProducts(String createDate, Pager<Product> pager, String channel){
		return getSoldoutProducts(createDate,pager, channel, " createDate desc ");
	}
	
	@Override
	public Pager<Product> getRepaidProducts(Pager<Product> pager){
		ProductExample example = new ProductExample();
		example.appendCriterion("tag=", 3);
		example.setOrderByClause(" id desc ");
		List<Product> list = productMapper.selectByExample(example, pager);
		int totalCount = productMapper.countByExample(example);
		pager.setTotalCount(totalCount);
		pager.setList(list);
		return pager;
	}


	/**
	 * 今日售完列表
	 */
	@Override
	public Pager<Product> getSoldoutProducts(String createDate, Pager<Product> pager, String channel, String orderBy) {
		if (pager != null) {
			ProductExample example = new ProductExample();
			example.appendCriterion(" (tag=4 or tag=3) ");
			
			if(StringUtils.isNotBlank(channel)){
				example.appendCriterion("(channel = '" + channel + "' or channel = '')");
			}
			else
				example.appendCriterion(" channel = '' ");
			
			if(StringUtils.isNotBlank(createDate))
				example.appendCriterion("date(startTime)=", createDate);
			if(StringUtils.isNotBlank(orderBy))
				example.setOrderByClause(orderBy);
			pager.setList(productMapper.selectByExample(example, pager));
			pager.setTotalCount(productMapper.countByExample(example));
		}
		return pager;
	}

	@Override
	public Product getProductBySerial(String serial) {
		Product product = null;
		if (serial != null) {
			ProductExample example = new ProductExample();
			example.appendCriterion("serial=", serial);
			product = productMapper.selectOneByExample(example);
			if (product != null) {
				FinancingExample financingExample = new FinancingExample();
				financingExample
						.appendCriterion("product_id=", product.getId());
				product.setNumberOfShoppers(financingMapper
						.countByExample(financingExample));
			}
		}
		return product;
	}

	@Override
	public Pager<Product> getAllProducts(Pager<Product> pager) {
		return getAllProducts(new ProductExample(), pager);
	}

	@Override
	public Pager<Product> getAllProducts(ProductExample exp,
			Pager<Product> pager) {
		pager.setList(productMapper.selectByExample(exp, pager));
		if (pager.getList() != null) {
			for (Product product : pager.getList()) {
				if (product.getId() != null) {
					FinancingExample financingExample = new FinancingExample();
					financingExample.appendCriterion("product_id=",
							product.getId());
					product.setNumberOfShoppers(financingMapper
							.countByExample(financingExample));
				}
			}
		}
		pager.setTotalCount(productMapper.countByExample(exp));
		return pager;
	}

	@Override
	public boolean saveProduct(Product product) throws BusinessException {

		/*
		 * 判断产品结束销售时间是否比开始销售时间迟5分钟以上
		 */
		if (product.getStartTime().getTime() + 5 * 60 * 1000 > product
				.getEndTime().getTime()) {
			throw new BusinessException("结束销售时间必须比开始销售时间迟5分钟以上");
		}

		// 钱滚翻
		if (product.getCategory() == Category.CURRENT) {
			if (product.getEarningsRules().size() < 1) {
				throw new BusinessException("未设置产品收益规则");
			}

			updateProductByEarningsRule(product);
		}

		// 产品编号
		String serial = commonService.getProductSerial();
		product.setSerial(serial);
		product.setCreateDate(new Date());
		product.setModifyDate(new Date());
		product.setSoldAmount(new BigDecimal(0));
		product.setUnpayAmount(new BigDecimal(0));
		product.setNumberOfShoppers(0);
		product.setStatus(Product.Status.EDITING);
		if (product.getDisplayTotalAmount() == null) {
			product.setDisplayTotalAmount(product.getTotalAmount());
		}
		if (product.getValueDate() == null) {
			product.setValueDate(new Date(0));
		}

		int row = productMapper.insert(product);
		if (row > 0) {
			addProductProductEarningsRules(product);
			addProductOutStock(product);
		}

		return row > 0;
	}

	/**
	 * 根据产品收益规则更新产品
	 * 
	 * @param product
	 *            产品
	 */
	private void updateProductByEarningsRule(Product product) {

		// 更新产品期限、收益
		ProductEarningsRule maxHoldingTimeRule = null;
		for (ProductEarningsRule rule : product.getEarningsRules()) {
			if (maxHoldingTimeRule == null
					|| rule.getHoldingTime() > maxHoldingTimeRule
							.getHoldingTime()) {
				maxHoldingTimeRule = rule;
			}
		}
		product.setTerm(maxHoldingTimeRule.getHoldingTime());
		product.setInterestRate(maxHoldingTimeRule.getInterestRate());
	}

	/**
	 * 添加产品收益规则
	 * 
	 * @param product
	 *            产品
	 * @throws BusinessException
	 */
	private void addProductProductEarningsRules(Product product)
			throws BusinessException {

		if (!Product.Category.CURRENT.equals(product.getCategory())) {
			return;
		}

		for (ProductEarningsRule rule : product.getEarningsRules()) {
			rule.setProduct(product);
			addProductEarningsRule(rule);
		}
	}

	/**
	 * 添加产品规则
	 * 
	 * @param rule
	 * @throws BusinessException
	 */
	private void addProductEarningsRule(ProductEarningsRule rule)
			throws BusinessException {

		if (rule.getProduct() == null) {
			throw new BusinessException("产品规则关联产品不能为空");
		}
		if (rule.getHoldingTime() == null) {
			throw new BusinessException("产品规则持有时间不能为空");
		}
		if (rule.getInterestRate() == null) {
			throw new BusinessException("产品规则年化收益不能为空");
		}

		rule.setCreateDate(new Date());
		rule.setModifyDate(new Date());
		setProductEarningsRule(rule.getProduct(), rule);

		if (this.productEarningsRuleMapper.insert(rule) < 1) {
			throw new BusinessException("插入产品规则失败");
		}
	}

	/**
	 * 设置产品收益规则相关属性值
	 * 
	 * @param product
	 *            产品
	 * @param rule
	 *            规则
	 */
	private void setProductEarningsRule(Product product,
			ProductEarningsRule rule) {
		// 到期日
		DateTime date = new DateTime(product.getValueDate()).plusDays(rule
				.getHoldingTime() - 1);
		rule.setDueDate(date.toDate());

		// 赎回日期
		// 提前4天赎回，赎回时间段7天
		rule.setRedemptionStartTime(date.minusDays(10).toDate());
		rule.setRedemptionEndTime(date.minusDays(4).toDate());
	}

	/**
	 * 添加产品出库
	 * 
	 * @param product
	 *            产品
	 */
	@Override
	public void addProductOutStock(Product product) {

		if (product.getFinancialAsset() == null
				|| product.getFinancialAsset().getId() == null) {
			return;
		}

		FinancialAsset financialAsset = this.financialAssetMapper
				.selectByPrimaryKey(product.getFinancialAsset().getId());
		if (product.getTotalAmount().compareTo(financialAsset.getInventory()) == 1) {
			throw new RuntimeException("产品金额大于金融资产库存金额");
		}

		FinancialAssetStockEntry entry = new FinancialAssetStockEntry();
		entry.setFinancialAsset(product.getFinancialAsset());
		entry.setPurpose(FinancialAssetStockEntry.Purpose.Sale);
		entry.setPostingDate(new Date());
		entry.setAmount(product.getTotalAmount());
		entry.setProduct(product);

		balanceAndFinancingService.outStock(entry);
	}

	@Override
	public BigDecimal calculateDayInterest(Long financing_id) {
		return null;
	}

	@Override
	public boolean deleteProduct(String serial) throws Exception {
		ProductExample example = new ProductExample();
		example.appendCriterion("serial=", serial);
		Product product = productMapper.selectOneByExample(example);
		if (product != null && product.getStatus() == Product.Status.EDITING) {

			// 用户已下单，不能删除
			if (isOrderInProduct(product)) {
				return false;
			}

			int row = productMapper.deleteByPrimaryKey(product);
			if (row > 0) {
				deleteProductEarningsRules(product);
				deleteProductInStock(product);
			}

			return row > 0;
		} else {
			return false;
		}
		// return productMapper.deleteByExample(example) > 0;
	}

	/**
	 * 删除产品收益规则
	 * 
	 * @param product
	 */
	private void deleteProductEarningsRules(Product product) {
		this.productEarningsRuleMapper
				.deleteProductEarningsRulesByProductId(product.getId());
	}

	/**
	 * 删除产品入库
	 * 
	 * @param product
	 *            产品
	 * @throws Exception
	 */
	private void deleteProductInStock(Product product) throws Exception {

		if (product.getFinancialAsset() == null
				|| product.getFinancialAsset().getId() == null) {
			return;
		}

		FinancialAssetStockEntry entry = new FinancialAssetStockEntry();
		entry.setFinancialAsset(product.getFinancialAsset());
		entry.setPurpose(FinancialAssetStockEntry.Purpose.DeleteProduct);
		entry.setPostingDate(new Date());
		entry.setAmount(product.getTotalAmount());
		entry.setProduct(product);

		balanceAndFinancingService.inStock(entry);

	}

	/**
	 * 产品是否已下单
	 * 
	 * @param product
	 *            产品
	 * @return true - 已下单，false - 未下单
	 */
	private boolean isOrderInProduct(Product product) {
		OrderExample example = new OrderExample();
		example.appendCriterion("product_id=", product.getId());
		int count = this.orderMapper.countByExample(example);
		return count > 0;
	}

	@Override
	public boolean updateProduct(Product product, String serial)
			throws BusinessException {
		/*
		 * 判断产品结束销售时间是否比开始销售时间迟5分钟以上
		 */
		if (product.getStartTime().getTime() + 5 * 60 * 1000 > product
				.getEndTime().getTime()) {
			throw new BusinessException("结束销售时间必须比开始销售时间迟5分钟以上");
		}
		ProductExample example = new ProductExample();
		example.appendCriterion("serial=", serial);
		Product p = productMapper.selectOneByExample(example);
		if (p == null) {
			return false;
		}

		if (Category.CURRENT == product.getCategory()) {
			updateProductByEarningsRule(product);
		}

		p.setModifyDate(new Date());
		p.setName(product.getName());
		p.setInterestRate(product.getInterestRate());
		p.setBonusRate(product.getBonusRate());
		p.setDisplayTotalAmount(product.getDisplayTotalAmount());
		p.setStartTime(product.getStartTime());
		p.setEndTime(product.getEndTime());
		p.setRiskLevel(product.getRiskLevel());
		p.setRiskDescription(product.getRiskDescription());
		p.setDescription(product.getDescription());
		p.setAppDescription(product.getAppDescription());
		p.setInsurance(product.getInsurance());
		p.setRemark(product.getRemark());
		
		if(product.getEndTime().after(new Date()))
			p.setTag(product.getTag());
		
		p.setSequnce(product.getSequnce());
		p.setMinAmount(product.getMinAmount());
		p.setValueDate(product.getValueDate());
		p.setMaxAmount(product.getMaxAmount());
		p.setType(product.getType());
		p.setActivitys(product.getActivitys());
		p.setAcceptingBank(product.getAcceptingBank());
		p.setRookie(product.getRookie());
		p.setEnterpriseCode(product.getEnterpriseCode());
		p.setChannel(product.getChannel());

		p.setTerm(product.getTerm());
		p.setMinTerm(product.getMinTerm());
		
		if (p.getFinancialAsset() != null) {
			if (p.getDueDate().compareTo(p.getFinancialAsset().getDueDate()) == 1) {
				throw new BusinessException("产品期限不能大于金融资产到期日");
			}
		}

		// 添加产品后，不能修改产品总金额、起息日，避免与资产库存不同步
		// product2.setValueDate(product.getValueDate());
		// product2.setTotalAmount(product.getTotalAmount());

		int count = productMapper.updateByPrimaryKey(p);
		if (count < 1) {
			return false;
		}

		return updateProductEarningsRules(product);
	}

	/**
	 * 更新产品规则
	 * 
	 * @param product
	 *            产品
	 * @return
	 * @throws BusinessException
	 */
	private boolean updateProductEarningsRules(Product product)
			throws BusinessException {
		if (null == product.getEarningsRules()) {
			return true;
		}

		Product oldProduct = this.productMapper.selectByPrimaryKey(product
				.getId());
		for (ProductEarningsRule rule : product.getEarningsRules()) {
			ProductEarningsRule r = this.productEarningsRuleMapper
					.selectByPrimaryKey(rule.getId());
			r.setModifyDate(new Date());
			r.setHoldingTime(rule.getHoldingTime());
			r.setInterestRate(rule.getInterestRate());
			setProductEarningsRule(oldProduct, r);
			if (this.productEarningsRuleMapper.updateByPrimaryKey(r) < 1) {
				throw new BusinessException("更新产品规则错误");
			}
		}
		return true;
	}

	@Override
	public boolean publishProduct(String serial) {

		ProductExample example = new ProductExample();
		example.appendCriterion("serial=", serial);
		Product product = productMapper.selectOneByExample(example);

		if (product == null) {
			return false;
		}

		if (product.getStatus() == Product.Status.EDITING) {
			product.setStatus(Product.Status.PUBLISHED);
			product.setPublishDate(new Date());
			sendSaleNotify(product);
			return productMapper.updateByPrimaryKey(product) > 0;

		} else if (product.getStatus() == Product.Status.PUBLISHED
				|| product.getStatus() == Product.Status.TIME_PUBLISH) {
			product.setStatus(Product.Status.EDITING);
			return productMapper.updateByPrimaryKey(product) < 0;
		} else {
			return false;
		}
		

	}

	// @Cacheable(value="product.cache",key="#key")
	@Override
	public Pager<Product> findProductsByPage(Map<String, Object> params,
			Pager<Product> pager) {
		if (pager != null) {
			pager.setList(productMapper.findProductsByPage(params, pager));

			for (Product product : pager.getList()) {
				FinancingExample financingExample = new FinancingExample();
				financingExample
						.appendCriterion("product_id=", product.getId());
				product.setNumberOfShoppers(financingMapper
						.countByExample(financingExample));
			}

			ProductExample example = new ProductExample();
			example.appendCriterion("(status = \'PUBLISHED\' or status = \'FINISHED\')");
			if (params != null && params.containsKey("tag")) {
				example.appendCriterion("tag=", params.get("tag"));
			}
			if (params != null && params.containsKey("rookie")) {
				example.appendCriterion("rookie=", params.get("rookie"));
			}
			if (params != null && params.containsKey("enterpriseCode")) {
				example.appendCriterion("enterpriseCode=",
						params.get("enterpriseCode"));
			}
			if (params != null && params.containsKey("nameNotLike")) {
				String[] nameNotLike = (String[]) params.get("nameNotLike");
				if (!isEmpty(nameNotLike)) {
					StringBuilder sb = new StringBuilder();
					sb.append('(');
					for (int i = 0; i < nameNotLike.length; i++) {
						sb.append("name NOT LIKE "
								+ quoteIfString("%" + nameNotLike[i] + "%"));
						if (i < nameNotLike.length - 1) {
							sb.append(" AND ");
						}
					}
					sb.append(')');
					example.appendCriterion(sb.toString());
				}
			}
			if (params != null && params.containsKey("notEnterpriseCode")) {
				example.appendCriterion("LENGTH(IFNULL(enterpriseCode,\'\'))<1");
			}
			if (params != null && params.containsKey("name")) {
				String name = params.get("name").toString();
				if ("其它".equals(name)) {
					example.appendCriterion("REPLACE(name,"
							+ quoteIfString("票据") + "," + quoteIfString("银票")
							+ ") not like \'%银票宝%\'");
					example.appendCriterion("REPLACE(name,"
							+ quoteIfString("票据") + "," + quoteIfString("银票")
							+ ") not like \'%月享%\'");
					example.appendCriterion("REPLACE(name,"
							+ quoteIfString("票据") + "," + quoteIfString("银票")
							+ ") not like \'%季享%\'");
				} else {
					example.appendCriterion("REPLACE(name,"
							+ quoteIfString("票据") + "," + quoteIfString("银票")
							+ ") like \'%" + params.get("name") + "%\'");
				}
			}
			pager.setTotalCount(productMapper.countByExample(example));
		}
		return pager;
	}

	@Override
	public boolean isProductPayback(Product product) {
		FinancingExample example = new FinancingExample();
		example.appendCriterion("product_id=", product.getId());
		int all = financingMapper.countByExample(example);
		example.appendCriterion("(status=\'" + Financing.Status.STATUS_PAYBACK
				+ "\' or status=\'" + Financing.Status.STATUS_REPAID + "\')");
		int paid = financingMapper.countByExample(example);
		if (all > 0 && paid > 0) {
			return all == paid;
		}
		return false;
	}

	@Override
	public Product getProductById(Long productId) {
		return productMapper.selectByPrimaryKey(productId);
	}

	@Override
	public void updateCashTime(Long id) {
		productMapper.updateCashTime(id);
	}

	@Override
	public boolean isTypeIdInUse(Long typeId) {
		ProductExample example = new ProductExample();
		example.appendCriterion("type_id = ", typeId);
		List<Product> list = productMapper.selectByExample(example,
				new Pager<Product>());
		if (list == null) {
			return false;
		} else if (list.size() == 0) {
			return false;
		}
		return true;
	}

	@Override
	public List<Product> findProductsByFinancialAssetId(Long id) {

		ProductExample example = new ProductExample();
		example.appendCriterion("financialAsset_id =", id);
		example.setOrderByClause("valueDate desc");

		Pager<Product> pager = new Pager<>();
		pager.setPageSize(10000);

		return this.productMapper.selectByExample(example, pager);
	}

	@Override
	public Integer findNumberOfShoppersByProduct(Product product) {
		FinancingExample financingExample = new FinancingExample();
		financingExample.appendCriterion("product_id=", product.getId());
		return financingMapper.countByExample(financingExample);
	}

	@Override
	public Product findLastProdutc(String param) {
		ProductExample example = new ProductExample();
		Pager<Product> pager = new Pager<>();
		pager.setPageSize(1);
		if ("month".equals(param)) {
			example.appendCriterion("term>", 20);
			example.appendCriterion("term<", 40);
			example.appendCriterion("name like", "%月享%");
		} else {
			example.appendCriterion("term>", 80);
			example.appendCriterion("term<", 100);
			example.appendCriterion("name like", "%季享%");
		}
		example.setOrderByClause("createDate desc");
		List<Product> products = productMapper.selectByExample(example, pager);
		if (products.size() > 0) {
			return products.get(0);
		}
		return null;
	}

	@Override
	public Pager<ProductType> listProductType(Pager<ProductType> pager) {
		ProductTypeExample exp = new ProductTypeExample();
		List<ProductType> list = productTypeMapper.selectByExample(exp, pager);
		int count = productTypeMapper.countByExample(exp);
		if (pager == null) {
			pager = new Pager<ProductType>();
		}
		pager.setList(list);
		pager.setTotalCount(count);
		return pager;
	}

	@Override
	public boolean updateProductType(ProductType type) {
		type.setModifyDate(new Date());
		if (type.getId() == null || type.getId().longValue() == 0) {
			type.setCreateDate(new Date());
			return productTypeMapper.insert(type) > 0;
		} else {
			return productTypeMapper.updateByPrimaryKey(type) > 0;
		}
	}

	@Override
	public ProductType getProductTypeById(Long id) {
		return productTypeMapper.selectByPrimaryKey(id);
	}

	@Override
	public void insertField(List<ProductTypeField> list) {
		for (ProductTypeField field : list) {
			field.setCreateDate(new Date());
			field.setModifyDate(new Date());
			fieldMapper.insert(field);
		}
	}

	@Override
	public List<ProductTypeField> findFieldsByTypeId(Long typeID) {
		if (typeID == null || typeID.longValue() == 0) {
			return null;
		}
		ProductTypeFieldExample example = new ProductTypeFieldExample();
		example.appendCriterion("typeId = ", typeID);
		Pager<ProductTypeField> pager = new Pager<>();
		pager.setPageSize(Integer.MAX_VALUE);
		return fieldMapper.selectByExample(example, pager);
	}

	@Override
	public boolean deleteField(Long typeId) {
		fieldMapper.deleteByProductTypeId(typeId);
		return true;
	}

	@Override
	public boolean insertProductTypeValue(ProductTypeValue productTypeValue) {
		productTypeValue.setCreateDate(new Date());
		return valueMapper.insert(productTypeValue) > 0;
	}

	@Override
	public boolean updateProductTypeValue(ProductTypeValue productTypeValue) {
		productTypeValue.setModifyDate(new Date());
		return valueMapper.updateByPrimaryKey(productTypeValue) > 0;
	}

	@Override
	public ProductTypeValue findProductTypeValueByProductId(Long productId) {
		ProductTypeValueExample example = new ProductTypeValueExample();
		example.appendCriterion("productId = ", productId);
		return valueMapper.selectOneByExample(example);
	}

	@Override
	public boolean deleteProductTypeValue(ProductTypeValue productTypeValue) {
		return valueMapper.deleteByPrimaryKey(productTypeValue) > 0;
	}

	@Override
	public Pager<Template> listTemplates(Pager<Template> pager) {
		TemplateExample example = new TemplateExample();

		pager.setList(templateMapper.selectByExample(example, pager));
		pager.setTotalCount(templateMapper.countByExample(example));
		return pager;
	}

	@Override
	public Pager<Template> getAllTemplateByCondition(TemplateExample example,
			Pager<Template> pager) {
		pager.setList(templateMapper.selectByExample(example, pager));
		pager.setTotalCount(templateMapper.countByExample(example));
		return pager;
	}

	@Override
	public boolean addTemplate(Template template) {
		template.setCreateDate(new Date());
		template.setModifyDate(new Date());
		template.setContent(StringEscapeUtils.unescapeHtml4(template
				.getContent()));
		return templateMapper.insert(template) > 0;
	}

	@Override
	public Template findLastedTemplate() {
		return templateMapper.findLastedTemplate();
	}

	@Override
	public List<Template> getAllTemplates() {
		TemplateExample example = new TemplateExample();
		Pager<Template> pager = new Pager<>();
		pager.setPageSize(Integer.MAX_VALUE);
		return getAllTemplateByCondition(example, pager).getList();
	}

	@Override
	public boolean deleteTemplateById(Long id) {
		Template template = new Template();
		template.setId(id);
		return (templateMapper.deleteByPrimaryKey(template) > 0);
	}

	@Override
	public Template getTemplateById(Long id) {
		return templateMapper.selectByPrimaryKey(id);
	}

	@Override
	public boolean updateTemplate(Template template) {
		template.setModifyDate(new Date());
		template.setContent(StringEscapeUtils.unescapeHtml4(template
				.getContent()));
		return (templateMapper.updateByPrimaryKey(template) > 0);

	}

	@Override
	public boolean insertEntity(TemplateValue templateValue) {
		templateValue.setCreateDate(new Date());
		templateValue.setModifyDate(new Date());
		return templateValueMapper.insert(templateValue) > 0;
	}

	@Override
	public boolean deleteByRelationId(String relationId) {
		templateValueMapper.deleteByRelationId(relationId);
		return true;
	}

	@Override
	public TemplateValue findTemplateValueByRelationId(Long relationId) {
		TemplateValueExample example = new TemplateValueExample();
		example.appendCriterion("relationId = ", relationId);
		return templateValueMapper.selectOneByExample(example);
	}

	@Override
	public boolean updateTemplateValue(TemplateValue templateValue) {
		templateValue.setModifyDate(new Date());
		return templateValueMapper.updateByPrimaryKey(templateValue) > 0;
	}

	@Override
	public TemplateValue findTemplateValueByRelationIdAndTemplateId(
			Long relationId, Long templateId) {
		TemplateValueExample example = new TemplateValueExample();
		example.appendCriterion("relationId = ", relationId);
		example.appendCriterion("templateId = ", templateId);
		return templateValueMapper.selectOneByExample(example);
	}

	@Override
	public void insertBatch(List<TemplateField> list) {
		for (TemplateField field : list) {
			field.setCreateDate(new Date());
			field.setModifyDate(new Date());
			templateFieldMapper.insert(field);
		}
	}

	@Override
	public List<TemplateField> findTemplateFieldsByTemplateId(Long templateId) {
		if (templateId == null || templateId.longValue() == 0) {
			return null;
		}
		TemplateFieldExample example = new TemplateFieldExample();
		example.appendCriterion("templateId = ", templateId);
		Pager<TemplateField> pager = new Pager<>();
		pager.setPageSize(Integer.MAX_VALUE);
		return getAllTemplateFieldsByCondition(example, pager).getList();
	}

	@Override
	public Pager<TemplateField> getAllTemplateFieldsByCondition(
			TemplateFieldExample example, Pager<TemplateField> pager) {
		pager.setList(templateFieldMapper.selectByExample(example, pager));
		pager.setTotalCount(templateFieldMapper.countByExample(example));
		return pager;
	}

	@Override
	public boolean deleteByTemplateId(Long templateId) {
		templateFieldMapper.deleteByTemplateId(templateId);
		return true;
	}

	/**
	 * 增加协议
	 *
	 * @param protocol
	 * @return
	 */
	public boolean addProtocol(Protocol protocol) {
		return protocolMapper.insert(protocol) > 0;
	}

	/**
	 * 修改协议
	 *
	 * @param protocol
	 * @return
	 */
	public boolean modifyProtocol(Protocol protocol) {
		return protocolMapper.updateByPrimaryKey(protocol) > 0;
	}

	/**
	 * 删除协议
	 *
	 * @param protocol
	 * @return
	 */
	public boolean deleteProtocol(Protocol protocol) {
		return protocolMapper.deleteByPrimaryKey(protocol) > 0;
	}

	/**
	 * 根据产品ID获取协议列表
	 *
	 * @param productId
	 * @return
	 */
	public List<Protocol> getProtocolsByProductId(Long productId) {
		ProtocolExample exp = new ProtocolExample();
		exp.appendCriterion("productId =", productId);

		return protocolMapper.selectByExample(exp, null);
	}

	@Override
	public Protocol findProtocolById(Long id) {
		return protocolMapper.selectByPrimaryKey(id);
	}

	@Override
	public void monitorProduct(Executor executor, final AlaudaSender sender) {
		productMapper.updateProductSale();
		// 发送通知
		ProductExample example = new ProductExample();
		example.appendCriterion("(endTime<now() OR (IFNULL(unpayAmount, 0) <= 0 AND totalAmount <= IFNULL(soldAmount, 0)))");
		example.appendCriterion("tag=", 2);
		example.appendCriterion("(status = "
				+ quoteIfString(Product.Status.PUBLISHED.toString())
				+ " or status = "
				+ quoteIfString(Product.Status.FINISHED.toString()) + ")");
		List<Map<String, String>> list = productMapper.findProductSoldOut();
		if (!CollectionUtils.isEmpty(list)) {
			for (Map<String, String> product : list) {
				
				Object serail = redisTemplate.opsForValue().get(
						"product_sold_out_" + product.get("serial"));
				logger.info("====================>serail:" + serail);
				if (serail == null) {
					//结标发送给用户
					sendNotifyForSoldout(product.get("serial"));
					
					// 发送购买成功jms
					logger.info("====================>HEJIA_SOLDOUT_EVENT_TOPIC开始"
							+ product.get("serial"));
					redisTemplate.opsForValue().set(
							"product_sold_out_" + product.get("serial"),
							product.get("serial"));
					redisTemplate.expire(
							"product_sold_out_" + product.get("serial"),
							60 * 12, TimeUnit.MINUTES);
					// Map<String, Object> item = new HashMap<String, Object>();
					// item.put("serial", product.getSerial());
					AlaudaEvent event = new AlaudaEvent();
					event.setEvent(AlaudaEvent.Event.EVENT_BUY_SUCCESS);
					event.setText(Utils.toJSON(product));
					sender.send(event, AlaudaEvent.HEJIA_SOLDOUT_EVENT_TOPIC);
					logger.info("====================>HEJIA_SOLDOUT_EVENT_TOPIC结束"
							+ product.get("serial"));
				}
			}
		}
		productMapper.updateProductSoldOut();
		productMapper.updateProductHaveHonour();
	}

	@Override
	public void setProductAgreementNumber(Long productId) {
		Product product = this.productMapper.selectByPrimaryKey(productId);
		if (StringUtils.isNotEmpty(product.getAgreementNumber())) {
			return;
		}

		int year = new DateTime(product.getCreateDate()).getYear();
		Set<String> productAgreementNumbers = this.productMapper
				.findProductAgreementNumbersByYear(year);
		String agreementNumber = getNewAgreementNumber(3,
				productAgreementNumbers);

		// 检查协议号是否已使用
		ProductExample example = new ProductExample();
		example.appendCriterion("year(createDate) =", year);
		example.appendCriterion("agreementNumber =", agreementNumber);
		if (this.productMapper.countByExample(example) > 0) {
			this.logger.error("资产协议号产品部分已被使用：" + agreementNumber);
			return;
		}

		this.productMapper.updateProductAgreementNumber(product.getId(),
				agreementNumber);
	}

	@Override
	public void setFinancingAgreementNumber(Long financingId) {
		Financing finacing = this.financingMapper
				.selectByPrimaryKey(financingId);
		if (StringUtils.isNotEmpty(finacing.getAgreementNumber())) {
			return;
		}

		Set<String> financingAgreementNumbers = this.productMapper
				.findFinancingAgreementNumbersByProductId(finacing.getProduct()
						.getId());
		String agreementNumber = getNewAgreementNumber(4,
				financingAgreementNumbers);

		// 检查协议号是否已使用
		FinancingExample example = new FinancingExample();
		example.appendCriterion("product_id =", finacing.getProduct().getId());
		example.appendCriterion("agreementNumber =", agreementNumber);
		if (this.financingMapper.countByExample(example) > 0) {
			this.logger.error("资产协议号资产部分已被使用：" + agreementNumber);
			return;
		}

		this.productMapper.updateFinancingAgreementNumber(finacing.getId(),
				agreementNumber);
	}

	/**
	 * 获取指定位数的协议号
	 * 
	 * @param digit
	 *            位数
	 * @param agreementNumbers
	 *            已有协议号
	 * @return 指定位数的协议号
	 */
	private String getNewAgreementNumber(int digit, Set<String> agreementNumbers) {

		String agreementNumber = "";
		int max = (int) Math.pow(36, digit); // 36进制

		Long start = System.currentTimeMillis();
		for (int i = 0; i < Integer.MAX_VALUE; i++) {
			int value = new Random().nextInt(max);
			String s = Long.toString(value, 36).toUpperCase();
			if (!agreementNumbers.contains(s)) {
				agreementNumber = s;
				break;
			}
		}

		Long time = System.currentTimeMillis() - start;
		if (time > 1000 * 3) {
			logger.error(String
					.format("getNewAgreementNumber方法执行时间过长：%s", time));
		}

		return StringUtils.leftPad(agreementNumber, digit, '0');
	}

	@Override
	public List<Product> findProductsByCategory(Category category) {
		ProductExample example = new ProductExample();
		if (category != null)
			example.appendCriterion("`category`=", category);
		return productMapper.selectByExample(example, null);
	}

	@Override
	public boolean timePublishProduct(String serial) {

		ProductExample example = new ProductExample();
		example.appendCriterion("serial=", serial);
		Product product = productMapper.selectOneByExample(example);
		if (Product.Status.EDITING != product.getStatus()) {
			return false;
		}

		product.setStatus(Product.Status.TIME_PUBLISH);
		return this.productMapper.updateByPrimaryKey(product) > 0;
	}

	@Override
	public void timePublishProducts() {

		ProductExample example = new ProductExample();
		example.appendCriterion("status =", Product.Status.TIME_PUBLISH);
		example.appendCriterion("startTime <", new DateTime().plusMinutes(30)
				.toDate());
		List<Product> products = this.productMapper.selectByExample(example,
				null);
		for (Product product : products) {
			product.setStatus(Product.Status.PUBLISHED);
			product.setPublishDate(new Date());
			this.productMapper.updateByPrimaryKey(product);
			sendSaleNotify(product);

		}
		
	}

	@Override
	public Product findLastRookieProdutc() {

		Pager<Product> pager = new Pager<>();
		pager.setPageSize(1);

		ProductExample example = new ProductExample();
		example.appendCriterion("rookie=1");
		example.setOrderByClause("createDate desc");
		List<Product> products = productMapper.selectByExample(example, pager);
		if (products.size() > 0) {
			return products.get(0);
		}
		return null;
	}

	@Override
	public void adjustProductTermByHoliday(Product product, Integer term,
			Integer maxTerm) {

		DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
		LocalDate endDate = new DateTime(product.getEndTime()).toLocalDate();
		for (int i = term; i <= maxTerm; i++) {
			boolean isInHoliday = false;
			LocalDate date = new DateTime(product.getStartTime()).toLocalDate();

			// 循环判断发售的每一天的兑付日是否节假日
			while (true) {
				if (this.calendarService.isHoliday(
						dateFormat.format(date.toDate()), i)) {
					isInHoliday = true;
					break;
				} else {
					date = date.plusDays(1);
					if (date.isAfter(endDate)) {
						break;
					}
				}
			}

			// 设置兑付日没有落到节假日的产品期限
			if (!isInHoliday) {
				product.setTerm(i);
				break;
			}
		}
	}

	@Override
	public void checkInventory(Product product) {

		if (product.getFinancialAsset() == null
				|| product.getFinancialAsset().getId() == null) {
			return;
		}

		FinancialAsset financialAsset = this.financialAssetMapper
				.selectByPrimaryKey(product.getFinancialAsset().getId());
		List<Presell> presells = this.presellService
				.findNotPublicPresellsByFinancialAssetId(product
						.getFinancialAsset().getId());

		BigDecimal presellAmount = BigDecimal.ZERO;
		for (Presell presell : presells) {
			presellAmount = presellAmount.add(presell.getTotalAmount());
		}

		BigDecimal amount = presellAmount.add(product.getTotalAmount());
		if (amount.compareTo(financialAsset.getInventory()) == 1) {
			throw new RuntimeException("产品金额加上排期预售金额大于金融资产库存金额");
		}
	}

	@Override
	public Pager<Product> findProductListByExample(ProductExample example,
			Pager<Product> pager, boolean isPagination) {
		if (isPagination) {
			pager.setList(productMapper.selectByExample(example, pager));
		} else {
			pager.setList(productMapper.selectByExample(example, null));
		}
		pager.setTotalCount(productMapper.countByExample(example));
		return pager;
	}

	@Override
	public Integer sumOnSellProductByCategoryAndAmount(Category category, boolean rookie, Integer availableSellAmount) {
		
		ProductExample example = new ProductExample();
		example.appendCriterion("status = 'PUBLISHED'");
		example.appendCriterion("tag in (1, 2)");
		example.appendCriterion("rookie = ", rookie);
		if (!rookie) {
			example.appendCriterion("category = ", category);
			example.appendCriterion("name like ", "快聚财 " + category.getName() + "%");
		}
		example.appendCriterion("(totalAmount - soldAmount + unpayAmount) >= ", availableSellAmount);
		return this.productMapper.countByExample(example);
	}

	@Override
	public Product findLastProdutc(Category category, boolean rookie) {
		
		Pager<Product> pager = new Pager<>();
		pager.setPageSize(1);
		
		ProductExample example = new ProductExample();
		example.appendCriterion("rookie = ", rookie);
		if (!rookie) {
			example.appendCriterion("category = ", category);
			example.appendCriterion("name like ", "快聚财 " + category.getName() + "%");
		}
		example.setOrderByClause("createDate desc");
		
		List<Product> products = this.productMapper.selectByExample(example, pager);
		if (products.size() < 1) {
			return null;
		}
		return products.get(0);
	}

	@Override
	public Integer findMaxProductNumber(Category category) {
		
		Product product = this.findLastProdutc(category, false);
		if (product == null) {
			return 0;
		}
		
		String productname = product.getName().trim();
		String regEx = "[^0-9]";
		Pattern p = Pattern.compile(regEx);
		Matcher m = p.matcher(productname);
		return Integer.parseInt(m.replaceAll(""));
	}

	@Override
	public void sendNotifyForSoldout(String serial) {
		Product product = getProductBySerial(serial);
		
		if(product.isCompletedValue()){
			//满标起息 TODO
		}
		
		logger.info("产品计息方式:"+product.getValueDateStr());
		if(product == null || "立即起息".equals(product.getValueDateStr()))
			return;
		logger.info("发送短信:");

		List<User> users = userMapper.findUsersByProduct(product.getId());
		for(User u:users){
			SMS sms = new SMS();
			sms.setMobile(u.getMobile());
			sms.setMessage("尊敬的"+u.getRealName()+",您参与的["+product.getName()+"]项目已经满标,今日开始计息,感谢您的支持!");
			sms.setChannel("alauda_notify");
			smsService.sendSMS(sms);
		}		
	}
	
	
	@Override
	public Integer countSaleNotify(){
		SaleNotifyExample example = new SaleNotifyExample();
		example.appendCriterion("enable=",1);
		example.appendCriterion("mobile is NOT NULL");
		example.setGroupByClause(" mobile ");
		int count = saleNotifyMapper.countByExample(example);
		return count;
		
	}
	
	@Override
	@Deprecated
	public void sendSaleNotify(String content){
		SaleNotifyExample example = new SaleNotifyExample();
		example.setDistinct(true);
		example.appendCriterion("enable=",1);
		example.appendCriterion("mobile is NOT NULL");
		example.setGroupByClause(" mobile ");
		List<SaleNotify> mobiles = saleNotifyMapper.selectByExample(example, null);
		for(SaleNotify notify:mobiles){
			SMS sms = new SMS();
			sms.setMobile(notify.getMobile());
			sms.setChannel("alauda_notify");
			sms.setMessage(content);
			smsService.sendSMS(sms);
		}
	}
	
	@Override
	public void sendSaleNotify(Date date){
		
		SaleNotifyExample example = new SaleNotifyExample();
		example.setDistinct(true);
		example.appendCriterion("enable=",1);
		example.appendCriterion("mobile is NOT NULL");
		example.setGroupByClause(" mobile ");
		List<SaleNotify> mobiles = saleNotifyMapper.selectByExample(example, null);
		for(SaleNotify notify:mobiles){
			SMS sms = new SMS();
			sms.setMobile(notify.getMobile());
			DateFormat dateFormatter = new SimpleDateFormat("HH:mm");
			String msg = String.format(SaleNotify.MSG_CONTENT, dateFormatter.format(date));
			sms.setChannel(SaleNotify.MSG_CONTENT);
			sms.setMessage(msg);
			smsService.sendSMS(sms);
			notify.setEnable(false);
			saleNotifyMapper.updateByPrimaryKey(notify);
		}
		
	}
	
	public List<Map<String, Object>> findFinancialListByProduct(Long productId){
		return productMapper.findFinancialListByProduct(productId);
	}

	/**
	 * 首页获取推荐产品
	 * 当前逻辑:取最新一个在售产品
	 * 
	 */
	@Override
	public Product getRecommendProductForHomePage(String channel) {
		Date now = new Date();
		ProductExample example = new ProductExample();
		example.appendCriterion("(IFNULL(unpayAmount,0)>0 or totalAmount>IFNULL(soldAmount,0))");
		//example.appendCriterion("startTime<=", now);
		example.appendCriterion("tag!=", 4);
		if(StringUtils.isNotBlank(channel))
			example.appendCriterion("channel=", channel);
		else 
			example.appendCriterion("channel= ''");
		example.appendCriterion("endTime>=", now);
		example.appendCriterion("rookie=", 0);
		example.appendCriterion("status=", "PUBLISHED");
		example.setOrderByClause("createDate desc");
		return productMapper.selectOneByExample(example);
	}

	
	/**
	 * 获取在售一个新手标
	 */
	@Override
	public Product getOnSaleRookieProduct() {
		Date now = new Date();
		ProductExample example = new ProductExample();
		example.appendCriterion("rookie=",1);
		example.appendCriterion("(IFNULL(unpayAmount,0)>0 or totalAmount>IFNULL(soldAmount,0))");
		example.appendCriterion("startTime<=", now);
		example.appendCriterion("endTime>=", now);
		example.setOrderByClause("createDate desc");
		return productMapper.selectOneByExample(example);
	}

	
	/**
	 * 根据产品号获取交易记录
	 */
	@Override
	public Pager<Financing> findProductTradeRecord(Product product, Pager<Financing> pager) {
		if(product == null)
			return null;
		
		pager.setOrderBy(" createDate desc ");
		
		return financingService.findFinancingByProduct(product, pager);
	}
	
	/**
	 * 根据活动id集合获取活动列表
	 * 
	 * @param aids
	 *            活动id集合
	 * @return
	 */
	@Override
	public List<SaleActivity> findProductSaleAcitvity(String aids) {
		List<SaleActivity> saList = new ArrayList<SaleActivity>();
		if (aids != null) {
			String[] aid = aids.split(",");
			for (int i = 0; aid != null && i < aid.length; i++) {
				SaleActivity activity = saleActivityService
						.findEffectiveActivityById(Long.parseLong(aid[i]));
				if (activity != null) {
					saList.add(activity);
				}
			}
		}
		return saList;
	}

	@Override
	public String renderingContent(com.hejia.alauda.entity.Template template,
			Product product) {
		if (template == null) {
			return null;
		}
		try {
			freemarker.template.Template tmplt = new freemarker.template.Template(template.getId().toString(),
					template.getContent(), null);
			StringWriter rest = new StringWriter();
			Map<String, Object> params = new HashMap<String, Object>();

			ProductTypeValue ptv = findProductTypeValueByProductId(product.getId());
			if (ptv != null) {
				JSONObject json = JSONObject.parseObject(ptv.getValue());
				Iterator<String> iterator = json.keySet().iterator();
				while (iterator.hasNext()) {
					String key = iterator.next();
					params.put(key, json.get(key));
				}
			}
			params.put("product", product);
			tmplt.process(params, rest);
			return rest.toString();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	
	public SaleActivity getInvitationSaleActivity(){
		SaleActivity activity = new SaleActivity();
		activity.setName("INVITATION");
		activity.setDescription("邀请好友有50元红包哦");
		activity.setUrl("http://m.kjc.cn/share/");
		return activity;
	}

	@Override
	public Boolean sendSaleNotify(Product product) {
		
		//新手标 或者 十分钟之内有发送过久不重复发送了
		if(StringUtils.isNotBlank(product.getChannel()) || product.getRookie() || System.currentTimeMillis() - lastSendTime < 10*60*1000)
			return false;
		
		lastSendTime = System.currentTimeMillis();
		
		Set<String> set = new HashSet<String>();
		SaleNotifyExample example = new SaleNotifyExample();
		example.appendCriterion(" enable=1 ");
		Pager<SaleNotify> pager = new Pager<SaleNotify>();
		pager.setPageSize(Integer.MAX_VALUE);
		List<SaleNotify> list = saleNotifyMapper.selectByExample(example, pager);
		for(SaleNotify s:list){
			if(!set.contains(s.getMobile())){
				set.add(s.getMobile());
				SMS sms = new SMS();
				sms.setMobile(s.getMobile());
				sms.setMessage("尊贵的快聚财客户,快聚财上新啦！数量有限，先到先得！");
				sms.setChannel("alauda_notify");
				smsService.sendSMS(sms);
			}
			s.setEnable(false);
			saleNotifyMapper.updateByPrimaryKey(s);
		}
	
		
		return true;
	}
}
